# -*- coding: utf-8 -*-

import copy
import json

import common
from merge_manager import MergerBase, MergeError
from thrift.protocol.TJSONProtocol import TSimpleJSONProtocol
from thrift.transport.TTransport import TMemoryBuffer


class MetaMerger(MergerBase):
    def __init__(self):
        pass
    def merge(self, task):
        '''
        元数据的merge

        时间相关的merge逻辑:
            每条记录有三个时间字段：_in_time(首次入库时间)，_utime(最新更新时间)，_src里的download_time(下载时间)。
            若相同_record_id的记录不存在：插入的记录中 _in_time = _utime = 当前时间。
            若相同_record_id的记录已存在：首先判断download_time，如果新数据的download_time比已有记录旧，就放弃插入并报错。
                如果新数据的download_time更新或与原来的相同，则进行插入操作，插入的记录中 _in_time保持不变，_utime修改为当前时间.

        上面的“当前时间”都是指该EntityExtractorInfo到达data_saver的时间
        '''
        current_datetime_str = task.accept_time.strftime(common.DATETIME_STR_FORMAT)
        
        task.current_entity_data = copy.deepcopy(task.old_entity_data)

        if not task.current_entity_data is None:
            # 获取旧数据中的download_time。若获取失败，则接受新数据。若获取成功，则在新数据的download_time相等或更新时接受新数据
            try:
                cur_download_time = task.current_entity_data[common.FIELDNAME_SOURCE][0]['download_time']
            except:
                task.current_entity_data[common.FIELDNAME_UTIME] = current_datetime_str
            else:
                new_download_time = task.entity_source.download_time
                #if new_download_time < cur_download_time:
                #    raise MergeError('New document has an older download_time[%s], old download_time[%s]' % (new_download_time, cur_download_time))
                task.current_entity_data[common.FIELDNAME_UTIME] = current_datetime_str
        else:
            # 新数据, 添加_in_time、_utime、_record_id三个元数据
            task.current_entity_data = {
                common.FIELDNAME_IN_TIME: current_datetime_str,
                common.FIELDNAME_UTIME: current_datetime_str,
                common.FIELDNAME_RECORD_ID: task.record_id
            }

        # 将entity_source转换为JSON, 合并到current_entity_data中(key=_src)
        t_mem_buf = TMemoryBuffer()
        t_json_protocol = TSimpleJSONProtocol(t_mem_buf)
        task.entity_source.write(t_json_protocol)
        new_src = json.loads(t_mem_buf.getvalue())
        new_site = str(new_src.get('site', None)).lower()
        if task.current_entity_data.has_key(common.FIELDNAME_SOURCE):
            found = False
            for i, old_src in enumerate(task.current_entity_data[common.FIELDNAME_SOURCE]):
                old_site = str(old_src.get('site', None)).lower()
                if old_site == new_site:
                    task.current_entity_data[common.FIELDNAME_SOURCE][i] = new_src
                    found = True
                    break
            if not found:
                task.current_entity_data[common.FIELDNAME_SOURCE].append(new_src)
        else:
            task.current_entity_data[common.FIELDNAME_SOURCE] = [new_src]
